import 'dart:async';
import 'package:flutter/material.dart';

// 浮动拖动按钮
class FloatingDragButton extends StatefulWidget {
  final Widget? iconWidget;
  final Color color;
  final double buttonWidth;
  final double buttonHeight;

  //点击事件
  final VoidCallback? onTap;

  const FloatingDragButton({
    super.key,
    this.iconWidget,
    this.buttonWidth = 40,
    this.buttonHeight = 40,
    this.color = Colors.blue,
    this.onTap,
  });

  @override
  State<FloatingDragButton> createState() => _FloatingDragButtonState();
}

class _FloatingDragButtonState extends State<FloatingDragButton> {
  double screenWidth = 0;
  double screenHeight = 0;
  double left = 0;
  double top = 0;
  double opacity = 1.0;
  bool isDragging = false;
  bool _isInit = false;

  // 点击定时器
  Timer? _clickTimer;

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
    _clickTimer?.cancel();
  }

  void _cancelClickTimer() {
    _clickTimer?.cancel();
    _clickTimer = null;
  }

  // 吸附
  void _updatePositionEnd({bool isAll = false}) {
    if (left < (screenWidth - widget.buttonWidth) / 2) {
      if (isAll) {
        left = 0;
      } else {
        left = -widget.buttonWidth / 2;
      }
    } else {
      if (isAll) {
        left = screenWidth - widget.buttonWidth;
      } else {
        left = screenWidth - widget.buttonWidth / 2;
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    //每次都刷新屏幕大小
    final newScreenWidth = MediaQuery.of(context).size.width;
    final newScreenHeight = MediaQuery.of(context).size.height;
    // 位置改变，吸附的地方也得改变
    bool sizeIsChanged = screenWidth != newScreenWidth || screenHeight != newScreenHeight;
    screenWidth = newScreenWidth;
    screenHeight = newScreenHeight;
    //初始化位置
    if (!_isInit) {
      _isInit = true;
      top = screenHeight / 2 - widget.buttonWidth / 2;
      left = -widget.buttonWidth / 2;
    } else if (sizeIsChanged && !isDragging) {
      _cancelClickTimer();
      _updatePositionEnd(isAll: false);
    }
    return AnimatedPositioned(
      duration: isDragging || sizeIsChanged ? Duration.zero : const Duration(milliseconds: 300),
      left: left,
      top: top,
      curve: Curves.bounceOut,
      child: GestureDetector(
        onTap: () {
          //显示出来2秒后隐藏
          setState(() {
            _updatePositionEnd(isAll: true);
          });
          _cancelClickTimer();
          _clickTimer = Timer(const Duration(seconds: 2), () {
            setState(() {
              _updatePositionEnd(isAll: false);
            });
          });
          widget.onTap?.call();
        },
        onPanStart: (details) {
          _cancelClickTimer();
          setState(() {
            isDragging = true;
            opacity = 0.6;
          });
        },
        onPanUpdate: (details) {
          _cancelClickTimer();
          setState(() {
            left = (left + details.delta.dx).clamp(0.0, screenWidth - widget.buttonWidth);
            top = (top + details.delta.dy).clamp(0.0, screenHeight - widget.buttonHeight);
          });
        },
        onPanEnd: (details) {
          _cancelClickTimer();
          setState(() {
            isDragging = false;
            opacity = 1.0;
            // 吸附到左边或右边
            _updatePositionEnd();
          });
        },
        child: AnimatedContainer(
          duration: const Duration(milliseconds: 300),
          curve: Curves.easeOut,
          width: widget.buttonWidth,
          height: widget.buttonHeight,
          decoration: BoxDecoration(
            color: widget.color.withValues(alpha: opacity),
            shape: widget.buttonWidth == widget.buttonHeight ? BoxShape.circle : BoxShape.rectangle,
            borderRadius: widget.buttonWidth != widget.buttonHeight ? BorderRadius.circular(widget.buttonWidth / 2) : null,
            boxShadow: [
              BoxShadow(
                color: Theme.of(context).shadowColor.withValues(alpha: 0.2),
                spreadRadius: 2,
                blurRadius: 5,
                offset: const Offset(0, 3),
              ),
            ],
          ),
          child: widget.iconWidget ?? const Icon(Icons.touch_app, color: Colors.white),
        ),
      ),
    );
  }
}
